package com.qd.http.tc.util;

import java.util.Map;

import org.apache.commons.lang3.StringUtils;

import com.qd.security.MD5Utils;
import com.qd.security.SHAUtils;

/**
 * @author taomk
 * @version 1.0
 * @since 2014/10/10 15:29
 */
public final class TcSignUtils {

	private TcSignUtils() {
	}

	/**
	 * 创建数字签名
	 *
	 * @param sign 存放数字签名参数的HashMap
	 * @return String DigitalSign
	 * @throws Exception
	 */
	public static String createXmlSign(Map<String, String> sign) {
		if (!sign.containsKey("accountKey") || sign.get("accountKey").trim().length() == 0) {
			return StringUtils.EMPTY;
		}
		String accountKey = sign.get("accountKey").trim(); // API帐户密钥

		String version = ""; // 版本号
		String serviceName = ""; // 调用接口的方法名称
		String accountId = ""; // API帐户密钥
		String reqTime = ""; // 当前日期

		if (sign.containsKey("version")) {
			version = sign.get("version");
		}

		if (sign.containsKey("serviceName")) {
			serviceName = sign.get("serviceName");
		}

		if (sign.containsKey("accountID")) {
			accountId = sign.get("accountID");
		}

		if (sign.containsKey("reqTime")) {
			reqTime = sign.get("reqTime");
		}

		String[] originalArray = {"Version=" + version,
				"AccountID=" + accountId, "ServiceName=" + serviceName,
				"ReqTime=" + reqTime};

		String[] sortedArray = bubbleSort(originalArray);

		return getMD5ByArray(sortedArray, accountKey, "UTF-8");
	}

	/**
	 * 获取字符数组的MD5哈希值
	 * @param sortedArray 待计算MD5哈希值的输入字符数组
	 * @param key         密钥
	 * @param charset     输入字符串的字符集
	 * @return 输入字符数组的MD5哈希值
	 */
	public static String getMD5ByArray(String[] sortedArray, String key, String charset) {
		// 构造待md5摘要字符串
		StringBuilder prestr = new StringBuilder();

		for (int i = 0; i < sortedArray.length; i++) {
			if (i == sortedArray.length - 1) {
				prestr.append(sortedArray[i]);
			} else {
				prestr.append(sortedArray[i] + "&");
			}
		}

		prestr.append(key);// 此处key为上面的innerKey

		return MD5Utils.md5(prestr.toString(), charset);
	}

	/**
	 * 数组排序（冒泡排序法）
	 *
	 * @param originalArray
	 *            待排序字符串数组
	 * @return 经过冒泡排序过的字符串数组
	 */
	public static String[] bubbleSort(String[] originalArray) {
		int i, j; // 交换标志
		String temp;
		Boolean exchange;

		for (i = 0; i < originalArray.length; i++) // 最多做R.Length-1趟排序
		{
			exchange = false; // 本趟排序开始前，交换标志应为假

			for (j = originalArray.length - 2; j >= i; j--) {
				if (originalArray[j + 1].compareTo(originalArray[j]) < 0)// 交换条件
				{
					temp = originalArray[j + 1];
					originalArray[j + 1] = originalArray[j];
					originalArray[j] = temp;

					exchange = true; // 发生了交换，故将交换标志置为真
				}
			}

			if (!exchange) // 本趟排序未发生交换，提前终止算法
			{
				break;
			}
		}

		return originalArray;
	}

	public static String createJsonSign(String module, String category, String methodName, String accountId, String password, String requestTime, int allianceId) {

		String fullActionName = module + "." + category + "." + methodName;
		String token = (fullActionName + "&" + accountId + "&" + password + "&" + requestTime).toLowerCase();

		return SHAUtils.sha1(token);
	}
}
